/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.opencvjava.code.nightingale.gui;
import com.opencvjava.code.nightingale.audio.Song;
import com.opencvjava.code.nightingale.interpretation.MeasureRow;
import com.opencvjava.code.nightingale.interpretation.Page;
import com.opencvjava.code.nightingale.interpretation.Symbol;

import javax.sound.midi.*;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;


import javax.imageio.ImageIO;

import javax.swing.ImageIcon;
import javax.swing.JFileChooser;



/**
 *
 * @author Caitlin
 */
public class Main extends javax.swing.JFrame {

	/**
	 * Creates new form Main
	 */
	public Main() {
		initComponents();
		try{
			String[] instruments = new String[Math.min(128, MidiSystem.getSynthesizer().getDefaultSoundbank().getInstruments().length)];
			int i = 0;
			for(Instrument inst : MidiSystem.getSynthesizer().getDefaultSoundbank().getInstruments()){
				instruments[i] = inst.getName();
				if(i>126)
					break;
				i++;
			}
			instrumentList.setListData(instruments);

		}
		catch(Exception e){
			e.printStackTrace();
			System.exit(0);
		}

	}
	public void drawSymbolBoxes(){
		pageImage.setIcon(new ImageIcon(displayedImage));
		Graphics imageGraphics = displayedImage.getGraphics();
		imageGraphics.setColor(new Color(0,255,200));
		for(MeasureRow mRow : p.measureRows){

			for(Symbol s : mRow.symbols){



				imageGraphics.setColor(new Color(255,0,0));
				if(selectedSymbols.contains(s)){
					imageGraphics.setColor(new Color(0,255,0));
				}
				if(s.playing == true){
					imageGraphics.setColor(new Color(0,0,255));

				}

				imageGraphics.drawRect(s.staffX, mRow.upperBound+s.staffY, s.myImage.getWidth(), s.myImage.getHeight());
			}
		}

	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	 @SuppressWarnings({ "unchecked", "rawtypes" })
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        fileChooser = new JFileChooser();
        scrollPane = new javax.swing.JScrollPane();
        pageImage = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        symbolInfoPanel = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        symbolType = new javax.swing.JComboBox();
        jLabel1 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        pitchSelector = new javax.swing.JComboBox();
        currentSymbolImage = new javax.swing.JLabel();
        applySymbolChangesButton = new javax.swing.JButton();
        measureInfoPanel = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        clefSelector = new javax.swing.JComboBox();
        jLabel7 = new javax.swing.JLabel();
        keySelector = new javax.swing.JComboBox();
        jLabel2 = new javax.swing.JLabel();
        songInfoPanel = new javax.swing.JPanel();
        jLabel5 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        tempoSelector = new javax.swing.JSpinner();
        jLabel9 = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        lengthLabel = new javax.swing.JLabel();
        timeSignatureText = new javax.swing.JTextField();
        playButton = new javax.swing.JButton();
        jLabel11 = new javax.swing.JLabel();
        instrumentListContainer = new javax.swing.JScrollPane();
        instrumentList = new javax.swing.JList();
        applySongChangesButton = new javax.swing.JButton();
        menuBar = new javax.swing.JMenuBar();
        fileMenu = new javax.swing.JMenu();
        importButton = new javax.swing.JMenuItem();
        editMenu = new javax.swing.JMenu();

        fileChooser.setCurrentDirectory(new File("C:\\Users\\Caitlin\\programming\\Senior Project\\Sheet music"));

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Nightingale");
        setMaximumSize(new java.awt.Dimension(2000, 1000));

        pageImage.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                pageImageMousePressed(evt);
            }
        });
        pageImage.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                pageImageKeyPressed(evt);
            }
        });
        scrollPane.setViewportView(pageImage);

        symbolInfoPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        symbolInfoPanel.setMaximumSize(new java.awt.Dimension(100, 200));
        symbolInfoPanel.setPreferredSize(new java.awt.Dimension(143, 111));

        jLabel3.setText("Symbol");

        symbolType.setEditable(true);
        symbolType.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "None", "Whole note", "Half note", "Quarter note", "Eighth note", "Sixteenth note", "Measure end", "Dot", "Sharp", "Flat", "Natural", "Treble clef", "Bass clef", "Alto clef", "Tie" }));
        symbolType.setActionCommand("");

        jLabel1.setText("Type");

        jLabel6.setText("Pitch");

        pitchSelector.setEditable(true);
        pitchSelector.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "B10", "A10", "G10", "F10", "E10", "D10", "C10", "B9", "A9", "G9", "F9", "E9", "D9", "C9", "B8", "A8", "G8", "F8", "E8", "D8", "C8", "B7", "A7", "G7", "F7", "E7", "D7", "C7", "B6", "A6", "G6", "F6", "E6", "D6", "C6", "B5", "A5", "G5", "F5", "E5", "D5", "C5", "B4", "A4", "G4", "F4", "E4", "D4", "C4", "B3", "A3", "G3", "F3", "E3", "D3", "C3" }));

        currentSymbolImage.setText(" ");

        applySymbolChangesButton.setText("Apply changes");
        applySymbolChangesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                applySymbolChangesButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout symbolInfoPanelLayout = new javax.swing.GroupLayout(symbolInfoPanel);
        symbolInfoPanel.setLayout(symbolInfoPanelLayout);
        symbolInfoPanelLayout.setHorizontalGroup(
            symbolInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(symbolInfoPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(symbolInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(symbolInfoPanelLayout.createSequentialGroup()
                        .addGroup(symbolInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1)
                            .addComponent(jLabel3)
                            .addComponent(jLabel6))
                        .addGap(27, 27, 27)
                        .addGroup(symbolInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(symbolInfoPanelLayout.createSequentialGroup()
                                .addComponent(symbolType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                            .addGroup(symbolInfoPanelLayout.createSequentialGroup()
                                .addComponent(pitchSelector, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(0, 0, Short.MAX_VALUE))))
                    .addGroup(symbolInfoPanelLayout.createSequentialGroup()
                        .addComponent(currentSymbolImage)
                        .addGap(0, 0, Short.MAX_VALUE))))
            .addGroup(symbolInfoPanelLayout.createSequentialGroup()
                .addComponent(applySymbolChangesButton)
                .addGap(0, 0, Short.MAX_VALUE))
        );
        symbolInfoPanelLayout.setVerticalGroup(
            symbolInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(symbolInfoPanelLayout.createSequentialGroup()
                .addComponent(jLabel3)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(symbolInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(symbolType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(symbolInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel6)
                    .addComponent(pitchSelector, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addComponent(currentSymbolImage)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 38, Short.MAX_VALUE)
                .addComponent(applySymbolChangesButton))
        );

        measureInfoPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        measureInfoPanel.setMaximumSize(new java.awt.Dimension(100, 200));

        jLabel4.setText("Measure");

        clefSelector.setEditable(true);
        clefSelector.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Treble", "Bass", "Alto" }));

        jLabel7.setText("Clef");

        keySelector.setEditable(true);
        keySelector.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "C major" }));

        jLabel2.setText("Key");

        javax.swing.GroupLayout measureInfoPanelLayout = new javax.swing.GroupLayout(measureInfoPanel);
        measureInfoPanel.setLayout(measureInfoPanelLayout);
        measureInfoPanelLayout.setHorizontalGroup(
            measureInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(measureInfoPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(measureInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(measureInfoPanelLayout.createSequentialGroup()
                        .addComponent(jLabel4)
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, measureInfoPanelLayout.createSequentialGroup()
                        .addGroup(measureInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(measureInfoPanelLayout.createSequentialGroup()
                                .addComponent(jLabel2)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(keySelector, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(measureInfoPanelLayout.createSequentialGroup()
                                .addComponent(jLabel7)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(clefSelector, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                        .addGap(28, 28, 28))))
        );
        measureInfoPanelLayout.setVerticalGroup(
            measureInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(measureInfoPanelLayout.createSequentialGroup()
                .addComponent(jLabel4)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(measureInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(clefSelector, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel7))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(measureInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(keySelector, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2))
                .addGap(0, 44, Short.MAX_VALUE))
        );

        songInfoPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        songInfoPanel.setMaximumSize(new java.awt.Dimension(100, 300));
        songInfoPanel.setPreferredSize(new java.awt.Dimension(123, 158));

        jLabel5.setText("Song");

        jLabel8.setText("Tempo");

        tempoSelector.setMinimumSize(new java.awt.Dimension(30, 20));
        tempoSelector.setName(""); // NOI18N
        tempoSelector.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                tempoSelectorStateChanged(evt);
            }
        });
        tempoSelector.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                tempoSelectorPropertyChange(evt);
            }
        });

        jLabel9.setText("Time signature");

        jLabel10.setText("Length");

        lengthLabel.setText("0");

        timeSignatureText.setText("4/4");
        timeSignatureText.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                timeSignatureTextActionPerformed(evt);
            }
        });

        playButton.setText("Play");
        playButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                playButtonActionPerformed(evt);
            }
        });

        jLabel11.setText("Instrument");

        instrumentList.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        instrumentListContainer.setViewportView(instrumentList);

        applySongChangesButton.setText("Apply changes");
        applySongChangesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                applySongChangesButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout songInfoPanelLayout = new javax.swing.GroupLayout(songInfoPanel);
        songInfoPanel.setLayout(songInfoPanelLayout);
        songInfoPanelLayout.setHorizontalGroup(
            songInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(songInfoPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(songInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(songInfoPanelLayout.createSequentialGroup()
                        .addComponent(jLabel5)
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(songInfoPanelLayout.createSequentialGroup()
                        .addGroup(songInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel8)
                            .addComponent(jLabel9)
                            .addComponent(jLabel10))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(songInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(tempoSelector, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addGroup(songInfoPanelLayout.createSequentialGroup()
                                .addGroup(songInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(lengthLabel)
                                    .addComponent(timeSignatureText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addGap(0, 0, Short.MAX_VALUE))))
                    .addGroup(songInfoPanelLayout.createSequentialGroup()
                        .addComponent(jLabel11)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(instrumentListContainer))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, songInfoPanelLayout.createSequentialGroup()
                        .addComponent(applySongChangesButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(playButton)))
                .addContainerGap())
        );
        songInfoPanelLayout.setVerticalGroup(
            songInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(songInfoPanelLayout.createSequentialGroup()
                .addComponent(jLabel5)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(songInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel8)
                    .addComponent(tempoSelector, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(songInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel9)
                    .addComponent(timeSignatureText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(songInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel10)
                    .addComponent(lengthLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(songInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel11)
                    .addComponent(instrumentListContainer, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 78, Short.MAX_VALUE)
                .addGroup(songInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(playButton)
                    .addComponent(applySongChangesButton))
                .addContainerGap())
        );

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(songInfoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 186, Short.MAX_VALUE)
                    .addComponent(measureInfoPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(symbolInfoPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 186, Short.MAX_VALUE))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(symbolInfoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 168, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(measureInfoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(songInfoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 237, Short.MAX_VALUE)
                .addContainerGap())
        );

        fileMenu.setText("File");

        importButton.setText("Import image");
        importButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                importButtonActionPerformed(evt);
            }
        });
        fileMenu.add(importButton);

        menuBar.add(fileMenu);

        editMenu.setText("Edit");
        menuBar.add(editMenu);

        setJMenuBar(menuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 597, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addComponent(scrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

	 private void importButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importButtonActionPerformed
		 mySong = null;
		 p = null;
		 int returnVal = fileChooser.showOpenDialog(this);
		 if (returnVal == JFileChooser.APPROVE_OPTION) {
			 File file = fileChooser.getSelectedFile();
			 try{
				 displayedImage = ImageIO.read(file);
				 pageImage.setIcon(new ImageIcon(displayedImage));
				 p = new Page(displayedImage);
				 p.buildPage();
				 drawSymbolBoxes();
			 }
			 catch(Exception e){
				 e.printStackTrace();
				 System.exit(ERROR);
			 }
		 }
		 else {
			 System.out.println("Not approved");
		 }
		 mySong = new Song(p);
		 mySong.myFrame = this;
		 lengthLabel.setText(mySong.lengthInSeconds()+"");
		 tempoSelector.setValue(new Integer(mySong.bpm));
	 }//GEN-LAST:event_importButtonActionPerformed

	 private void pageImageMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_pageImageMousePressed
		 int x = evt.getX();
		 int y = evt.getY();
		 y -= (pageImage.getHeight()-p.wholePage.getHeight())/2;
		 String[] basicNotes = new String[]{"B","A","G","F","E","D","C"};
		 String[] notes = new String[78];
		 for(int i = 10; i > -1; i--){
			 for(int n = 0; n < 7; n++){
				 notes[i*7+n] = basicNotes[6-n]+""+i;
			 }
		 }

		 for (MeasureRow mRow : p.measureRows){
			 for(Symbol s : mRow.symbols){
				 if(s.staffX<x&&s.staffY+mRow.upperBound<y&&s.staffX+s.myImage.getWidth()>x&&s.staffY+mRow.upperBound+s.myImage.getHeight()>=y){
					 if(selectedSymbols.size()>0)
						 selectedSymbols.remove(0);
					 selectedSymbols.add(s);
					 symbolType.setSelectedItem((s.type));
					 if(s.type.contains("note"))
						 pitchSelector.setSelectedItem(notes[28-((mRow.evalPitch(s.noteHeads.get(0)[1]+s.staffY)))]);
					 else
						 pitchSelector.setSelectedItem("None");
					 clefSelector.setSelectedItem(mRow.clef);
					 keySelector.setSelectedItem(mRow.key);

				 }
			 }
		 }
		 resetPageImage();
		 drawSymbolBoxes();
		 currentSymbolImage.setIcon(new ImageIcon(selectedSymbols.get(0).myImage));

	 }//GEN-LAST:event_pageImageMousePressed

	 private void pageImageKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_pageImageKeyPressed

	 }//GEN-LAST:event_pageImageKeyPressed

	 private void timeSignatureTextActionPerformed(java.awt.event.ActionEvent evt) {
		 String[] t = timeSignatureText.getText().split("/");
		 mySong.timeSignature = new int[]{Integer.parseInt(t[0]), Integer.parseInt(t[1])};
	 }

	 private void tempoSelectorPropertyChange(java.beans.PropertyChangeEvent evt) {
		 if(mySong!=null)
			 mySong.bpm = (Integer)tempoSelector.getValue();
	 }

	 private void tempoSelectorStateChanged(javax.swing.event.ChangeEvent evt) {
		 if(mySong!=null){
			 mySong.bpm = (Integer)tempoSelector.getValue();
			 lengthLabel.setText(""+mySong.lengthInSeconds());
		 }

	 }

	 private void tempoSelectorMouseClicked(java.awt.event.MouseEvent evt) {

	 }

	 private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed
		 mySong.makeNoteSequence();
		 mySong.makeMidiSequence();
		 lengthLabel.setText(""+mySong.lengthInSeconds());
		 mySong.play();
	 }//GEN-LAST:event_playButtonActionPerformed

    private void symbolTypeItemStateChanged(java.awt.event.ItemEvent evt){
    	selectedSymbols.get(0).type=(String) symbolType.getSelectedItem();
    }

    private void applySymbolChangesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applySymbolChangesButtonActionPerformed
        selectedSymbols.get(0).type=(String) symbolType.getSelectedItem();

        if(!selectedSymbols.get(0).type.contains("note")){
            return;
        }

        int y = pitchSelector.getSelectedIndex() - 48;
        int measureRowOfNote = 0;
        while(p.measureRows.get(measureRowOfNote).lowerBound<selectedSymbols.get(0).staffY){
            measureRowOfNote++;
        }
        if(p.measureRows.get(measureRowOfNote).clef.equals("Treble"))
            y = 11 + y;
        if(p.measureRows.get(measureRowOfNote).clef.equals("Alto"))
            y = 4 + y;
        if(p.measureRows.get(measureRowOfNote).clef.equals("Bass"))
            y = -2 + y;
        y *= selectedSymbols.get(0).staffDist/2;
        y -= selectedSymbols.get(0).staffY;
        y += p.measureRows.get(measureRowOfNote).staffLines[0][0];
        selectedSymbols.get(0).noteHeads.set(0, new int[]{0,y,0});
    }//GEN-LAST:event_applySymbolChangesButtonActionPerformed

    private void applySongChangesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applySongChangesButtonActionPerformed
        String[] t = timeSignatureText.getText().split("/");
        mySong.timeSignature = new int[]{Integer.parseInt(t[0]), Integer.parseInt(t[1])};
        mySong.instrument = instrumentList.getSelectedIndex();
        if(mySong!=null){
            mySong.bpm = (Integer)tempoSelector.getValue();
            System.out.print("New tempo: "+mySong.bpm);
	   }
    }//GEN-LAST:event_applySongChangesButtonActionPerformed

	 /**
	  * @param args the command line arguments
	  */
	 public static void main(String args[]) {
		 /* Set the Nimbus look and feel */
		 //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
		 /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
		  * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
		  */
		 try {
			 for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
				 if ("Nimbus".equals(info.getName())) {
					 javax.swing.UIManager.setLookAndFeel(info.getClassName());
					 break;
				 }
			 }
		 } catch (ClassNotFoundException ex) {
			 java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
		 } catch (InstantiationException ex) {
			 java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
		 } catch (IllegalAccessException ex) {
			 java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
		 } catch (javax.swing.UnsupportedLookAndFeelException ex) {
			 java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
		 }
		 //</editor-fold>

		 /* Create and display the form */
		 java.awt.EventQueue.invokeLater(new Runnable() {
			 public void run() {
				 new Main().setVisible(true);
			 }
		 });
	 }

	 private void resetPageImage(){
		 pageImage.setIcon(new ImageIcon(p.wholePage));
		 displayedImage = p.wholePage;
	 }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton applySongChangesButton;
    private javax.swing.JButton applySymbolChangesButton;
    private javax.swing.JComboBox clefSelector;
    private javax.swing.JLabel currentSymbolImage;
    private javax.swing.JMenu editMenu;
    private JFileChooser fileChooser;
    private javax.swing.JMenu fileMenu;
    private javax.swing.JMenuItem importButton;
    private javax.swing.JList instrumentList;
    private javax.swing.JScrollPane instrumentListContainer;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JComboBox keySelector;
    private javax.swing.JLabel lengthLabel;
    private javax.swing.JPanel measureInfoPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JLabel pageImage;
    private javax.swing.JComboBox pitchSelector;
    private javax.swing.JButton playButton;
    private javax.swing.JScrollPane scrollPane;
    private javax.swing.JPanel songInfoPanel;
    private javax.swing.JPanel symbolInfoPanel;
    private javax.swing.JComboBox symbolType;
    private javax.swing.JSpinner tempoSelector;
    private javax.swing.JTextField timeSignatureText;
    // End of variables declaration//GEN-END:variables
	 private Page p;
	 private Song mySong;
	 private BufferedImage displayedImage;
	 private ArrayList<Symbol> selectedSymbols = new ArrayList<>();

}
